package com.spc.car.web.controller.file;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spc.car.common.utils.file.FileUtils;
import com.spc.car.core.framework.web.domain.AjaxResult;
import com.spc.car.data.constant.CommConstants;
import com.spc.car.data.domain.attach.po.FilePO;
import com.spc.car.data.entity.project.ProjectTenderingProject;
import com.spc.car.data.entity.sys.SysAttachment;
import com.spc.car.data.service.project.ProjectTenderingProjectService;
import com.spc.car.data.service.sys.SysAttachmentService;
import com.spc.car.service.file.FileService;
import com.spc.car.web.controller.BaseController;
import com.spc.car.web.log.ProjectAction;
import com.spc.car.web.log.annotation.LogProjectAction;
import com.spc.car.web.log.annotation.LogSpel;
import com.spc.car.web.log.module.LogSysAttachment;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "文件")
@Validated
@Slf4j
@RequestMapping("/file")
@RestController
public class FileController extends BaseController {

    @Autowired
    SysAttachmentService attachmentService;

    @Autowired
    private FileService fileService;

    @Value("${oa.attach.url}")
    private String filePtah;

    @Autowired
    private ProjectTenderingProjectService projectRelationService;

    @LogSpel("#{#principal.getUsername()}上传文件#{#multipartFile.getOriginalFilename()}")
    @PreAuthorize("hasPermission(#params, 'uploadFileParams', 'project:edit')")
    @LogProjectAction(action = {ProjectAction.UPLOAD_ATTACHMENT},clz = LogSysAttachment.class)
    @ApiOperation(value = "上传文件", notes = "上传文件")
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile multipartFile,
                             @RequestParam(name = "params", required = false) String params) {
        Map<String, Object> paramMaps = new HashMap<>();
        if (StringUtils.isNotBlank(params)) {
            paramMaps = JSON.parseObject(params, Map.class);
        }

        SysAttachment sysAttachment = fileService.upload(multipartFile, filePtah, paramMaps, getPrintUser());

        return AjaxResult.success("文件上传成功", sysAttachment);
    }

    @LogProjectAction(action = {ProjectAction.UPLOAD_ATTACHMENT}, clz = LogSysAttachment.class)
    @ApiOperation(value = "行政管理附件上传", notes = "上传附件和行政相关的")
    @PostMapping("/admUploadAttach")
    public AjaxResult admUploadAttach(@RequestParam("file") MultipartFile multipartFile,
                                      @RequestParam(name = "params", required = false) String params) {

        Map<String, Object> paramMaps = new HashMap<>();
        if (StringUtils.isNotBlank(params)) {
            paramMaps = JSON.parseObject(params, Map.class);
        }

        SysAttachment sysAttachment =
                fileService.upload(multipartFile, filePtah.replace("/project", "/adm").trim(),
                        paramMaps, getPrintUser());

        AjaxResult ajaxResult = AjaxResult.success();
        ajaxResult.put("file", sysAttachment.getFileUrl());
        return ajaxResult;
    }

    @ApiOperation(value = "文件下载", notes = "文件下载")
    @GetMapping("/download")
    public void download(@RequestParam("fileId") Long fileId, HttpServletResponse response, HttpServletRequest request) {
        try {

            SysAttachment attachment = attachmentService.getById(fileId);
            String realFileName = StringUtils.join(
                    attachment.getFileName(),
                    attachment.getVersion(),
                    attachment.getFileSuffix());

            String filePath = attachment.getFileUrl();

            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
            FileUtils.writeBytes(filePath, response.getOutputStream());
        } catch (Exception e) {
            log.info("文件下载失败{}", e);
        }
    }

    @ApiOperation(value = "获取文件列表", notes = "获取文件列表")
    @PostMapping("/list")
    public AjaxResult list(@RequestBody FilePO filePO) {
        QueryWrapper wrapper = (QueryWrapper) filePO.toWrapper();
        if (StringUtils.isBlank(filePO.getProjectCode()) && null == filePO.getDeptId()) {
            wrapper.eq("file_owner", getPrintUser().getUserName());
        }
        if (StringUtils.isNotBlank(filePO.getProjectCode())) {
            if (filePO.getProjectCode().startsWith("PT")) {
                List<ProjectTenderingProject> projectRelations = projectRelationService.list(
                        new QueryWrapper<ProjectTenderingProject>()
                                .eq("project_tendering_code", filePO.getProjectCode()));
                List<String> projectCodeList = new ArrayList<>();
                projectCodeList.add(filePO.getProjectCode());
                if (CollectionUtils.isNotEmpty(projectRelations)) {
                    projectCodeList.addAll(
                      projectRelations.stream()
                              .map(ProjectTenderingProject::getProjectCode)
                              .collect(Collectors.toList())
                    );
                }
                wrapper.in("project_code", projectCodeList);
            } else {
                wrapper.eq("project_code", filePO.getProjectCode());
            }
        }
        Page<SysAttachment> attachmentList = attachmentService.page(
                new Page(filePO.getPage(), filePO.getPageSize()),
                wrapper);
        return AjaxResult.success("获取文件列表成功", attachmentList);
    }

    @ApiOperation(value = "获取文件信息", notes = "获取文件信息")
    @GetMapping("/getFileInfo")
    public AjaxResult getFileInfo(@RequestParam("fileId") Long fileId) {
        SysAttachment sysAttachment = attachmentService.getById(fileId);
        return null == sysAttachment ? AjaxResult.error("没有匹配的文件")
                : AjaxResult.success("获取文件信息成功", sysAttachment);
    }

    @LogProjectAction(action = {ProjectAction.REMOVE_ATTACHMENT},
            idForPost = "fileId", clz = LogSysAttachment.class)
    @ApiOperation(value = "移除文件", notes = "移除文件")
    @PreAuthorize("@ss.hasAnyPermi('sys:file:remove')")
    @PostMapping("/remove")
    public AjaxResult remove(@RequestParam("fileId") Long fileId) {
        SysAttachment sysAttachment = attachmentService.getById(fileId);
        if (null == sysAttachment) {
            return AjaxResult.error("没有匹配的文件");
        }
        sysAttachment.setStatus(CommConstants.FileConstants.FILE_STATUS_DEL);
        attachmentService.updateById(sysAttachment);

        return AjaxResult.success("移除文件成功");
    }

}
